#ifndef __H_D3D_MESH__
#define __H_D3D_MESH__
#include <vector>
using namespace std;

#define SAFE_DELETE(n)\
do \
{\
	if (n)\
	{\
		delete n;\
		n = NULL;\
	}\
} while (false);

struct BoneInf
{
	ULONG boneId;
	float weight;
};

struct VertexSkin
{
	vector<BoneInf>	vecBone;
	ULONG vertIdx;
};

class D3DVert
{
public:
	Point3	pos;
	Point3	normal;
	Point2	uv;

	int original;

	int operator == (const D3DVert& p) const { return (pos == p.pos && normal == p.normal && uv == p.uv); }
	int operator != (const D3DVert& p) const { return ( (pos != p.pos) || (normal != p.normal) || (uv != p.uv) ); }
};

struct SubMeshD3D
{
	int mtlID;
	vector<D3DVert>	vert_list;
	vector<IPoint3>	face_list;
};

class CD3DMesh
{
public:
	CD3DMesh();
	~CD3DMesh();

	void Clear();
	bool Convert();
	void Write(IXMLDOMDocument * pXMLDoc, CComPtr<IXMLDOMNode> parent);

	void AddVertex(Point3& v)	{ _vertex_list.push_back(v);	}
	void AddNormal(Point3& n)	{ _normal_list.push_back(n);	}
	void AddUV(Point2& uv)		{ _uv_list.push_back(uv);		}

	void AddFaceVert(IPoint3& face)	{ _face_vert_list.push_back(face);	}
	void AddFaceNormal(IPoint3& face)	{ _face_normal_list.push_back(face); }
	void AddFaceUV(IPoint3& face)	{ _face_uv_list.push_back(face);	}
	void AddMaterialID(int mtlID) { _face_mtl_id.push_back(mtlID); }
	
	void AddVertexSkin(VertexSkin& vs)	{ _vertex_skin_list.push_back(vs);	}

private:
	int __FindMaxMtlID();
	void __ExpandAllVertex(SubMeshD3D& subMesh, vector<D3DVert>& vec);
	void __CombineSameVertex(vector<D3DVert>& vecExpanded, vector<int>& vecVertexIdx);
	void __AdjustFaceIndex(SubMeshD3D& subMesh, vector<int>& vecVertexIdx);
	void __StoreResult(SubMeshD3D& subMesh, vector<D3DVert>& vecExpanded, vector<int>& vecVertexIdx);
	void __WriteSubMesh(SubMeshD3D& subMesh, IXMLDOMDocument* pXMLDoc, CComPtr<IXMLDOMNode> parent);

private:
	vector<Point3>		_vertex_list;
	vector<Point3>		_normal_list;
	vector<Point2>		_uv_list;

	vector<IPoint3>		_face_vert_list;
	vector<IPoint3>		_face_normal_list;
	vector<IPoint3>		_face_uv_list;
	vector<int>				_face_mtl_id;

	vector<VertexSkin>	_vertex_skin_list;

	vector<SubMeshD3D> _vecSubMeshD3D;
};

#endif